#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <vector>
#include <string>
#include <cstdio>
#include <cstring>
#include "LockGuard.hpp"

#define NUM 4

// 用多线程，模拟一轮抢票
int tickets = 1000;

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

class threadData
{
public:
    threadData(int number /*, pthread_mutex_t *mutex*/)
    {
        threadname += "thread-" + std::to_string(number);
        // lock = mutex;
    }
    std::string Getname()
    {
        return threadname;
    }
    // pthread_mutex_t *Getlock()
    // {
    //     return this->lock;
    // }

private:
    std::string threadname;
    // pthread_mutex_t *lock;
};

void *getTicket(void *args)
{
    threadData *td = static_cast<threadData *>(args);
    std::string name = td->Getname();
    while (true)
    {
        {
            // RAII风格的锁
            LockGuard lockguard(&lock); // 临时的LockGuard对象
            if (tickets > 0)
            {
                usleep(1000);
                std::cout << "who=" << name << ", get a ticket: " << tickets << std::endl;
                tickets--;
            }
            else
                break;
        }
        usleep(13);
    }
    std::cout << name << " ... quit" << std::endl;
    return nullptr;
}

// void *getTicket(void *args)
// {
//     threadData *td = static_cast<threadData *>(args);
//     std::string name = td->Getname();
//     while (true)
//     {
//         // 加锁
//         // 申请锁成功，才能往后执行，不成功则阻塞等待
//         // pthread_mutex_lock(td->Getlock());
//         pthread_mutex_lock(&lock);
//         if (tickets > 0)
//         {
//             usleep(1000);
//             std::cout << "who=" << name << ", get a ticket: " << tickets << std::endl;
//             tickets--;
//             // 减锁
//             // pthread_mutex_unlock(td->Getlock());
//             // pthread_mutex_unlock(&lock);
//         }
//         else
//         {
//             // 减锁
//             // pthread_mutex_unlock(td->Getlock());
//             pthread_mutex_unlock(&lock);
//             break;
//         }
//         usleep(13);
//     }
//     std::cout << name << " ... quit" << std::endl;
//     return nullptr;
// }

int main()
{
    // pthread_mutex_t lock;
    // pthread_mutex_init(&lock, nullptr);

    std::vector<pthread_t> tids;
    std::vector<threadData *> thread_datas;
    // 创建多线程
    for (int i = 1; i <= NUM; i++)
    {
        pthread_t tid;
        threadData *td = new threadData(i /*, &lock*/);
        thread_datas.push_back(td);
        pthread_create(&tid, nullptr, getTicket, thread_datas[i - 1]);
        tids.push_back(tid);
    }

    // 等待新线程结束
    for (auto thread : tids)
    {
        pthread_join(thread, nullptr);
    }
    // 释放
    for (auto td : thread_datas)
    {
        delete td;
    }

    pthread_mutex_destroy(&lock);
    return 0;
}